// 云函数入口文件
const cloud = require('wx-server-sdk')
const nodeExcel = require('excel-export')
const path = require('path')
const moment = require("moment")
const MAX_LIMIT = 100

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false;
  context.TIMEOUT_TIME_LIMIT = 60000; // 设置为一分钟（60000毫秒）

  let { isManual } = event;
  if (!isManual) {
    isManual = false
  }
  var team = "scu14";
  var tableHead = ["名次", "编号", "姓名", "跑步卡", "力量卡", "越野卡", "跳绳", "爬楼", "周训", "活动卡","瑜伽卡", "已打跑步卡", "已打力量卡", "本周积分", "本月积分", "本周请假", "本周警告", "当月跑量"];
  var tableMap = {
    styleXmlFile: path.join(__dirname, "styles.xml"),
    name: Date.now() + "-export",
    cols: [],
    rows: [],
  }

  //添加表头  此处要注意格式type，会影响到rows
  //列信息：包括标题及类型
  tableMap.cols = [
    {
      caption: tableHead[0],
      type: 'number'
    }, {
      caption: tableHead[1],
      type: 'string'
    }, {
      caption: tableHead[2],
      type: 'string'
    }, {
      caption: tableHead[3],
      type: 'number'
    }, {
      caption: tableHead[4],
      type: 'number'
    }, {
      caption: tableHead[5],
      type: 'number'
    }, {
      caption: tableHead[6],
      type: 'number'
    }
    , {
      caption: tableHead[7],
      type: 'number'
    }
    , {
      caption: tableHead[8],
      type: 'number'
    }
    , {
      caption: tableHead[9],
      type: 'number'
    }, {
      caption: tableHead[10],
      type: 'number'
    }
    , {
      caption: tableHead[11],
      type: 'boolean'
    }
    , {
      caption: tableHead[12],
      type: 'boolean'
    }
    , {
      caption: tableHead[13],
      type: 'number'
    }
    , {
      caption: tableHead[14],
      type: 'number'
    }
    , {
      caption: tableHead[15],
      type: 'boolean'
    },
    {
      caption: tableHead[16],
      type: 'boolean'
    },
    {
      caption: tableHead[17],
      type: 'number'
    },
  ]

  const db = cloud.database()
  const _ = db.command

  // 查询团队成员总数
  const userCount = await db.collection('user').where({
    isMember: true,
    team: team
  }).count()
  const userTotal = userCount.total

  // 计算需分几次取
  const userBatchTimes = Math.ceil(userTotal / MAX_LIMIT)
  const userTasks = []

  // 分批查询团队成员信息
  for (let i = 0; i < userBatchTimes; i++) {
    const promise = db.collection('user').where({
      isMember: true,
      isOut: false,
      team: team
    }).orderBy('point', 'desc').skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
    userTasks.push(promise)
  }

  // 合并查询结果
  const userData = (await Promise.all(userTasks)).reduce((acc, cur) => {
    return {
      data: acc.data.concat(cur.data),
      errMsg: acc.errMsg,
    }
  })

  let userList = userData.data

  // 获取本周和本月的起始和结束日期
  moment.locale('zh-cn');
  var m = moment().utcOffset(480)
  m.set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
  const startWeekDate = m.week(moment().week() - 1).startOf('week').valueOf();
  const endWeekDate = m.week(moment().week() - 1).endOf('week').valueOf();

  var month = moment().utcOffset(480)
  month.set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
  const startMonthDate = month.startOf('month').valueOf();
  const endMonthDate = month.endOf('month').valueOf();

  // 并行查询所有用户的打卡记录和请假记录
  const cardTasks = userList.map(user => {
    return db.collection('cards').where({
      _openid: user._openid,
      systemTime: _.lte(endMonthDate).and(_.gte(startMonthDate)),
    }).get()
  })

  const absenceTasks = userList.map(user => {
    return db.collection('absence-list').where({
      _openid: user._openid,
      systemTime: _.lte(endWeekDate).and(_.gte(startWeekDate)),
    }).count()
  })

  const [cardResults, absenceResults] = await Promise.all([Promise.all(cardTasks), Promise.all(absenceTasks)])

  const Output = [] // 存储输出数据的数组

  // 循环处理团队成员数据
  for (let i = 0; i < userList.length; i++) {
    let user = userList[i]
    let cards = cardResults[i].data
    let absenceCount = absenceResults[i].total

    var weekPoints = Array(8).fill(0)
    var totleWeekPoint = 0
    var hasRunning = false
    var hasGym = false
    var totleMonthPoint = 0
    var monthDistance = 0

    // 统计本周和本月的打卡情况
    cards.forEach(card => {
      if (card.status == 'checked') {
        if (card.systemTime >= startWeekDate && card.systemTime <= endWeekDate) {
          weekPoints[card.type.index] += card.point
          if ((card.type.index == 0 || card.type.index == 2) && parseFloat(card.distance) >= 3) {
            hasRunning = true
          }
        }
        if (card.systemTime >= startMonthDate && card.systemTime <= endMonthDate) {
          totleMonthPoint += card.point
          if (card.type.index == 0 || card.type.index == 2) {
            monthDistance += parseFloat(card.distance)
          }
        }
      }
    })

    totleWeekPoint = weekPoints.reduce((sum, points) => sum + points, 0)
    hasGym = weekPoints[1] != 0

    let isAbsence = absenceCount > 0
    let hasCompleteSport = hasGym && hasRunning
    let hasWarnning = !hasCompleteSport && !isAbsence

    Output.push({
      名次: i + 1,
      编号: user.index,
      姓名: user.nickName,
      跑步卡: weekPoints[0],
      力量卡: weekPoints[1],
      越野卡: weekPoints[2],
      跳绳卡: weekPoints[3],
      爬楼卡: weekPoints[4],
      周训: weekPoints[5],
      活动卡: weekPoints[6],
      瑜伽卡: weekPoints[7],
      已打跑步卡: hasRunning,
      已打力量卡: hasGym,
      本周积分: totleWeekPoint,
      本月积分: totleMonthPoint,
      本周请假: isAbsence,
      本周警告: hasWarnning,
      当月跑量: monthDistance
    })

    // 更新本周是否警告的数据
    if (!isManual) {
      db.collection('user').where({
        _openid: user._openid,
      }).update({
        data: {
          isLastAbsence: user.isAbsence,
          isAbsence: isAbsence,
          isLastWeekWarning: user.isWeekWarning,
          isWeekWarning: hasWarnning,
        }
      })
    }
  }

  // 添加每一行数据
  for (var i = 0; i < Output.length; i++) {
    tableMap.rows.push([
      Output[i].名次,
      Output[i].编号,
      Output[i].姓名,
      Output[i].跑步卡,
      Output[i].力量卡,
      Output[i].越野卡,
      Output[i].跳绳卡,
      Output[i].爬楼卡,
      Output[i].周训,
      Output[i].活动卡,
      Output[i].瑜伽卡,
      Output[i].已打跑步卡,
      Output[i].已打力量卡,
      Output[i].本周积分,
      Output[i].本月积分,
      Output[i].本周请假,
      Output[i].本周警告,
      Output[i].当月跑量,
    ])
  }

  // 生成Excel文件并上传到云存储中
  var excelResult = nodeExcel.execute(tableMap);
  var filePath = "outputExcels";
  var date = moment().add(8, 'hours').format('YYYY_MM_DD_hh_mm');
  var fileName = date + '川行者积分统计情况.xlsx';
  return await cloud.uploadFile({
    cloudPath: path.join(filePath, fileName),
    fileContent: Buffer.from(excelResult, 'binary')
  });
}
